package com.example.system.information.mq;

import com.example.system.information.BuildConfig;
import com.example.system.information.bean.DeviceInfoRecord;
import com.google.gson.Gson;
import com.rabbitmq.client.*;

import java.io.IOException;
import java.net.ConnectException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeoutException;

/**
 * mq-队列推送
 */
public class MQUtils {
    private static final String EXCHANGE_NAME = "amq.fanout";  // 使用 fanout 交换机
    private static final String QUEUE_NAME = "equipment_info_mqtt";  // 队列名称
    private static final ExecutorService executor = Executors.newSingleThreadExecutor();

    /**
     * 异步推送系统信息到 MQ
     */
    public static void pushSystemInfo(final DeviceInfoRecord record) {
        executor.submit(new Runnable() {
            @Override
            public void run() {
                Connection connection = null;
                Channel channel = null;

                try {
                    ConnectionFactory factory = new ConnectionFactory();
                    factory.setHost(BuildConfig.MqttUrl);
                    factory.setPort(BuildConfig.MqttProt);
                    factory.setUsername(BuildConfig.MqttUserName);
                    factory.setPassword(BuildConfig.MqttPassword);
                    factory.setVirtualHost("/");
                    // 设置连接超时时间（毫秒）
                    factory.setConnectionTimeout(10000);
                    // 设置自动恢复连接
                    factory.setAutomaticRecoveryEnabled(true);
                    factory.setNetworkRecoveryInterval(5000);

                    System.out.println("开始连接 RabbitMQ 服务器...");
                    connection = factory.newConnection();
                    System.out.println("连接成功");

                    channel = connection.createChannel();

                    // 声明队列（如果不存在）
                    channel.queueDeclare(QUEUE_NAME, true, false, false, null);

                    // 将队列绑定到 fanout 交换机（重要！）
                    channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "");
                    System.out.println("队列 " + QUEUE_NAME + " 已绑定到交换机 " + EXCHANGE_NAME);

                    // 转换为 JSON 并发送消息到交换机
                    String message = new Gson().toJson(record);
                    channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes("UTF-8"));
                    System.out.println("消息发送成功: " + message);

                    // 启用发布确认
                    channel.confirmSelect();

                    // 等待确认（同步方式）
                    if (channel.waitForConfirms()) {
                        System.out.println("MQ服务器确认接收消息");
                    } else {
                        System.out.println("MQ服务器未确认接收消息");
                    }

                } catch (ConnectException e) {
                    System.err.println("连接被拒绝，请检查服务器地址和端口: " + e.getMessage());
                    e.printStackTrace();
                } catch (AuthenticationFailureException e) {
                    System.err.println("认证失败，请检查用户名和密码: " + e.getMessage());
                    e.printStackTrace();
                } catch (IOException | TimeoutException | InterruptedException e) {
                    System.err.println("网络异常或连接超时: " + e.getMessage());
                    e.printStackTrace();
                } catch (Exception e) {
                    System.err.println("未知异常: " + e.getMessage());
                    e.printStackTrace();
                } finally {
                    // 关闭资源
                    closeChannel(channel);
                    closeConnection(connection);
                }
            }
        });
    }

    /**
     * 安全关闭 Channel
     */
    private static void closeChannel(Channel channel) {
        if (channel != null && channel.isOpen()) {
            try {
                channel.close();
            } catch (IOException | TimeoutException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 安全关闭 Connection
     */
    private static void closeConnection(Connection connection) {
        if (connection != null && connection.isOpen()) {
            try {
                connection.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 关闭线程池（在应用退出时调用）
     */
    public static void shutdown() {
        executor.shutdown();
    }
}
